package ccb.ygqd.inspur.sign;


import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Base64;

import com.siecomzg.constconfig.ErrorDefine;
import com.siecomzg.tool.BitmapUtil;
import com.siecomzg.tool.LogUtil;
import com.siecomzg.transport.DeviceCallback;
import com.siecomzg.transport.SiecomDevice;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import ccb.ygqd.inspur.common.ConstHF;

public class Sign  {


    private static final String TAG = Sign.class.getSimpleName();
    private Context mContext;

    public Sign(Context context){
        mContext = context;
    }
    /**
     *
     * @param iIndex 主密匙号 取值1-8
     * @param signData 用于存储加密后的轨迹数据 1024*1024 客户端负责分配空间，把DES加密后的轨迹数据拷贝到此数组中 注：16进制
     * @param strWorkKey 经主密钥加密后的工作密钥
     * @param strSignPicPath 签名的矢量图的保存路径，PNG格式
     * @param strTimeout 默认为30秒
     * @return 正确返回时：aryRet[0]为“DRV0000000”，aryRet[1]为加密后的签名轨迹数据的长度。aryRet[2]为电子签名厂家代码：6：升腾，9：长城，10：三泰，20：国光
     */
    public String[] getSignature(int iIndex, byte[] signData, String strWorkKey, String strSignPicPath, String strTimeout){
        LogUtil.e(TAG,"getSignature ==== " );
        return null;
    }

    /**
     * 对签名设备进行密钥灌注。
     * @param keys 8组主密钥
     * @return
     */
    public String[] keyAffuse (String[] keys){
        return null;
    }

    /**
     * 对签名返回的DES加密轨迹数据进行解密，得到解密后的String数据
     * @param workKey 解密密匙
     * @param signData 签名返回的加密轨迹数据
     * @param signDataLen 指定轨迹数据的长度
     * @return aryRet[0]为“DRV0000000”;aryRet[1]为解密后的轨迹数据。
     */
    public String[] getDecodeData (String workKey,byte[] signData, int signDataLen){
        return null;
    }
    //=============新方案=================================================================

    /**
     * 10.4.获取签名数据（新接口，新方案使用）要求客户进行签名，并获取签名数据。新接口，用于电子签名模块新的安全加密方案
     * @param iAlgorithm 密钥算法类型
     * @param iIndex 主密匙号 取值1-8
     * @param strWorkKey 经主密钥加密后的工作密钥
     * @param strTimeout 默认为30秒
     * @return 正确返回时：aryRet[0]为“DRV0000000”，
     * aryRet[1]为加密后的签名轨迹数据的长度。
     * aryRet[2]为电子签名厂家代码：6：升腾，9：长城，10：三泰，20：国光；
     * aryRet[3]为电子签名图片base64编码后的数据；
     * aryRet[4]为轨迹数据加密后再经base64编码的数据；
     */
    public String[] getSignatureEx(int iAlgorithm, int iIndex, String strWorkKey, String strTimeout){
        final String[] ret = new String[]{"","","","",""};
        if (!SiecomDevice.isConnected){
            ret[0] = ConstHF.ERR_NOT_CONN;
            ret[1] = ConstHF.ERR_DEV_ONT_CONN;
            return ret;
        }
        int timeOut = Integer.parseInt(strTimeout);
        final CountDownLatch latch = new CountDownLatch(1);
        iIndex = iIndex > 6 ? 5 : iIndex;

        JSONObject jb = new JSONObject();
        try {
            jb.put("type",2); //国密
            jb.put("index",iIndex);
            jb.put("workKey",strWorkKey);
            jb.put("width",10); // 0 根据压感变化
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
        SiecomDevice.getSignature( new DeviceCallback() {
            @Override
            public void onStart() {
                LogUtil.e(TAG,"getSignature onStart == "  );
            }

            @Override
            public void onError(Bundle bundle) {
                ret[0] = ConstHF.ERR_SIGN_NOT_SIGN; //默认签名错误
                int code = bundle.getInt("code");
                if (code == ErrorDefine.SIGNATURE_USER_CANCEL || code == ErrorDefine.SIGNATURE_ADMIN_CANCEL )
                    ret[0] = ConstHF.ERR_USER_CANCEL;
                if (code == ErrorDefine.TIME_OUT || code == ErrorDefine.SIGNATURE_TIMEOUT)
                    ret[0] = ConstHF.ERR_TIME_OUT;
                String msg = bundle.getString("message");
                ret[1] = msg;

                latch.countDown();
            }

            @Override
            public void onSuccess(Bundle bundle) {
                LogUtil.e(TAG,"getSignature onSuccess == "  );
                Bitmap signature = bundle.getParcelable("data");
                String trackStr = bundle.getString("track");
                String lenStr = trackStr.length() + "";
                ret[0] = ConstHF.ERR_SUCCESS;
                ret[1] = lenStr;  // 为加密后的签名轨迹数据的长度。
                ret[2] = "21"; //电子签名厂家代码
                ret[3] = BitmapUtil.bitmapToBase64(signature, Base64.NO_WRAP);  //图片base64
                ret[4] = Base64.encodeToString(trackStr.getBytes(),Base64.NO_WRAP);//轨迹数据加密后再经base64编码的数据

                latch.countDown();
            }

            @Override
            public void onCompleted(Bundle bundle) {

                latch.countDown();
            }
        },timeOut*1000,"10",jb.toString(),false);

        try {
            latch.await(timeOut + 2, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        return ret;
    }

    /**
     *
     * @param iAlgorithm 1：SM4密钥
     * @param iMainKeyId 密钥索引ID
     * @param strKeys 密钥数据，由byte[]转为16进制的字符串
     * @return aryRet[0]为错误代码，aryRet[1]为错误描述。
     */
    public String[] loadMainKey (int iAlgorithm, int iMainKeyId, String strKeys){
        final String[] ret = new String[]{"","","","",""};
        if (!SiecomDevice.isConnected){
            ret[0] = ConstHF.ERR_NOT_CONN;
            ret[1] = ConstHF.ERR_DEV_ONT_CONN;
            return ret;
        }
        int timeOut = 5;
        final CountDownLatch latch = new CountDownLatch(1);
        if (iAlgorithm == 1) iAlgorithm = 2;
        SiecomDevice.setSignMainKey(strKeys,iMainKeyId,2, new DeviceCallback() {
            @Override
            public void onStart() {

            }

            @Override
            public void onError(Bundle bundle) {
                ret[0] = ConstHF.ERR_INNER_ERROR;
                latch.countDown();
            }

            @Override
            public void onSuccess(Bundle bundle) {
                ret[0] = ConstHF.ERR_SUCCESS;
                latch.countDown();
            }

            @Override
            public void onCompleted(Bundle bundle) {
                latch.countDown();
            }
        },timeOut*1000,false);
        try {
            latch.await(timeOut + 1, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return ret;
    }

    public String[] ygbSmSupport(){
        return new String[]{ConstHF.ERR_SUCCESS};
    }


}
